package com.itheima.tanhua.server.controller;

import cn.hutool.core.util.RandomUtil;
import com.itheima.commons.holder.TokenHolderUserId;
import com.itheima.commons.utils.JwtUtils;
import com.itheima.tanhua.autoconfig.template.AipFaceTemplate;
import com.itheima.tanhua.autoconfig.template.OssTemplate;
import com.itheima.tanhua.dubbo.service.UserService;
import com.itheima.tanhua.model.domain.User;
import com.itheima.tanhua.model.domain.UserInfo;
import com.itheima.tanhua.model.dto.LoginRegInfoDto;
import com.itheima.tanhua.model.dto.LoginVerificationDto;
import com.itheima.tanhua.model.vo.LoginVerificationVo;
import org.apache.commons.lang.StringUtils;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.TimeUnit;

/**
 * @author H Monster
 */
@RestController
@RequestMapping("/user")
public class UserController {

    @DubboReference
    private UserService userService;

    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private OssTemplate ossTemplate;

    @Autowired
    private AipFaceTemplate aipFaceTemplate;

    /**
     * 获取验证码
     *
     * @param loginVerificationDto 手机号验证码
     * @return int
     */
    @PostMapping("/login")
    public ResponseEntity getPhoneCode(@RequestBody LoginVerificationDto loginVerificationDto) {
        // 获取四位数验证码
        String verifyCode = RandomUtil.randomNumbers(4);
        System.out.println(verifyCode);

        // 获取用户手机号
        String phone = loginVerificationDto.getPhone();

        // 存入数据
        redisTemplate.opsForValue().set(phone, verifyCode, 3600, TimeUnit.SECONDS);

        return ResponseEntity.ok(verifyCode);

    }

    /**
     * 验证码校验
     *
     * @param loginVerificationDto 手机号验证码
     * @return String
     */
    @PostMapping("/loginVerification")
    public LoginVerificationVo loginVerification(@RequestBody LoginVerificationDto loginVerificationDto) throws Exception {
        // 获取键
        String phone = loginVerificationDto.getPhone();

        // 根据键, 获取redis值
        String code = (String) redisTemplate.opsForValue().get(phone);

        // 获取前端传过来的验证码
        String verificationCode = loginVerificationDto.getVerificationCode();

        // 返回错误
        if (StringUtils.isEmpty(phone) || StringUtils.isEmpty(code)) {
            throw new Exception("手机号或验证码不能为空");
        }

        // 验证码比对
        if (!verificationCode.equals(code)) {
            throw new Exception("验证码失效");
        }

        // 根据接口文档可以知道，返回值需要带上一个isNew字段，这个字段是给前端用来判断是新用户还是就用户的
        boolean isNew = false;

        // 查询当前手机号是否存在
        User userInfo = userService.getUserByPhone(phone);
        if (Objects.isNull(userInfo)) {
            // 注册
            userInfo = userService.createUserByPhone(phone);
            isNew = true;
        }

        // 生成token
        Map<String, Object> map = new HashMap<>(1);
        map.put("phone", userInfo.getMobile());
        map.put("userId", userInfo.getId());

        String token = JwtUtils.getToken(map);

        LoginVerificationVo vo = new LoginVerificationVo();
        vo.setIsNew(isNew);
        vo.setToken(token);

        return vo;

    }

    /**
     * 完善用户信息
     *
     * @param loginRegInfoDto 封装类
     */
    @PostMapping("/loginReginfo")
    public void loginRegInfo(@RequestBody LoginRegInfoDto loginRegInfoDto) {
//        // 判断token是否有效
//        boolean isEffective = JwtUtils.verifyToken(authorization);
//        // 有效
//        if (isEffective) {
//            // 获取存入token中的claims信息
//            Claims claims = JwtUtils.getClaims(authorization);
//            System.out.println(claims);
//
//            // 获取存入token中的信息
//            Integer userId = (Integer) claims.get("userId");
//            System.out.println(userId);
//
//            //赋值
//            loginRegInfoDto.setId(userId);
//
//            userService.insertUserInfo(loginRegInfoDto);
//        } else {
//            throw new Exception("token失效");
//        }
        UserInfo userInfo = new UserInfo();

        BeanUtils.copyProperties(loginRegInfoDto, userInfo);

        String userId = TokenHolderUserId.get();

        userInfo.setId(userId);

        userService.createUserInfo(userInfo);

    }

    /**
     * 阿里云oss上传图片
     *
     * @param file 文件
     * @param path 路径
     * @return ResponseEntity
     */
    @PostMapping("/oss")
    public ResponseEntity templateUpload(@RequestParam("file") MultipartFile file, String path) throws IOException {

        // String path = "D:\\bbb.png";

        InputStream is = file.getInputStream();

        String imageUrl = ossTemplate.upload(path, is);

        System.out.println(imageUrl);

        return ResponseEntity.ok("ok");
    }

    /**
     * 百度人脸识别
     *
     * @param image 图片
     */
    @GetMapping("/face")
    public void detectFace(String image) {
        // String image = "https://moster-m.oss-cn-hangzhou.aliyuncs.com/2022/03/06/0d4bdfb8-22c4-4f10-b288-39c9cb682392.png";

        boolean detect = aipFaceTemplate.detect(image);

        System.out.println(detect);
    }

    /**
     * 补充头像
     *
     * @param headPhoto 图片文件
     */
    @PostMapping("/loginReginfo/head")
    public void loginHead(@RequestParam("headPhoto") MultipartFile headPhoto) throws Exception {
        //1. 将图片上传至阿里云OSS
        String imageUrl = ossTemplate.upload(headPhoto.getOriginalFilename(), headPhoto.getInputStream());

        //2. 调用百度云人脸识别判断是否包含人脸
        boolean result = aipFaceTemplate.detect(imageUrl);

        //获取userId
        String userId = TokenHolderUserId.get();

        //2.1 不包含人脸抛出异常
        if (!result) {
            throw new Exception("图片不包含人脸,请重新上传");
        } else {
            //2.2 包含人脸,调用方法更新
            UserInfo userInfo = new UserInfo();
            userInfo.setId(userId);
            userInfo.setAvatar(imageUrl);
            //调用service
            userService.updateHead(userInfo);
        }
    }
}


